package cmd

import (
	"docker-api/internal/domain"
	"docker-api/internal/model"
	"encoding/json"
	"errors"
	"fmt"
	"os/exec"
	"strings"
)

// DockerInfo 包含 Docker 基本信息
type DockerInfo struct {
	Version    string
	APIVersion string
	OS         string
	Arch       string
}

// ComposeInfo 包含 Docker Compose 信息
type ComposeInfo struct {
	Version string
}

// DockerCommandExecutor Docker 命令执行器接口
type DockerCommandExecutor interface {
	GetVersion() (*DockerInfo, error)
	GetComposeVersion() (*ComposeInfo, error)
	IsDockerRunning() bool
}

// SystemCommandExecutor 系统命令执行器接口
type SystemCommandExecutor interface {
	GetSystemInfo() (*SystemInfo, error)
}

// GetVersion 获取 Docker 版本信息
func GetVersion() (*DockerInfo, error) {
	// 使用 docker version --format json 获取完整信息
	cmd := exec.Command("docker", "version", "--format", "json")
	output, err := ExecuteCommand(cmd)
	if err != nil {
		// 如果 JSON 格式失败，尝试使用分别获取的方式
		return GetVersionFallback()
	}

	return ParseDockerVersionJSON(output)
}

// GetComposeVersion 获取 Docker Compose 版本信息
func GetComposeVersion() (*ComposeInfo, error) {
	cmd := exec.Command("docker", "compose", "version", "--short")
	output, err := ExecuteCommand(cmd)
	if err != nil {
		return nil, fmt.Errorf("获取 Docker Compose 版本失败: %w", err)
	}

	version := strings.TrimSpace(output)
	if version == "" {
		return nil, errors.New("Docker Compose 版本信息为空")
	}

	return &ComposeInfo{Version: version}, nil
}

// IsDockerRunning 检查 Docker 服务是否运行
func IsDockerRunning() bool {
	cmd := exec.Command("docker", "info")
	err := cmd.Run()
	return err == nil
}

// DockerVersionResponse Docker version 命令的响应结构
type DockerVersionResponse struct {
	Server struct {
		Version    string `json:"Version"`
		APIVersion string `json:"ApiVersion"`
		OS         string `json:"Os"`
		Arch       string `json:"Arch"`
	} `json:"Server"`
}

// GetVersionFallback 备用方案获取版本信息
func GetVersionFallback() (*DockerInfo, error) {
	// 使用传统的 docker version 命令获取文本格式输出
	cmd := exec.Command("docker", "version")
	output, err := ExecuteCommand(cmd)
	if err != nil {
		return nil, fmt.Errorf("获取 Docker 版本失败: %w", err)
	}
	return ParseDockerVersionText(output)
}

// 保持向后兼容的全局函数
// GetDockerInfo 获取 Docker 信息（向后兼容）
func GetDockerInfo() (*DockerInfo, error) {
	return GetVersion()
}

// GetComposeInfo 获取 Docker Compose 信息（向后兼容）
func GetComposeInfo() (*ComposeInfo, error) {
	return GetComposeVersion()
}

// GetAllImageIDs 获取所有 Docker 镜像 ID
func GetAllImageIDs() ([]string, error) {
	cmd := exec.Command("docker", "images", "--format", "{{.ID}}")
	output, err := ExecuteCommand(cmd)
	if err != nil {
		return nil, fmt.Errorf("获取镜像列表失败: %w", err)
	}

	imageIDs := strings.Split(strings.TrimSpace(output), "\n")
	// 过滤空 ID
	var validIDs []string
	for _, id := range imageIDs {
		if id != "" {
			validIDs = append(validIDs, id)
		}
	}
	return validIDs, nil
}

// GetImageDetail 获取单个镜像的详细信息
func GetImageDetail(imageID string) ([]model.DockerImage, error) {
	cmd := exec.Command("docker", "inspect", imageID)
	output, err := ExecuteSystemCommandRaw(cmd)
	if err != nil {
		return nil, fmt.Errorf("获取镜像详情失败: %w", err)
	}

	var inspectResults []domain.DockerImageInfo
	if err := json.Unmarshal(output, &inspectResults); err != nil {
		return nil, fmt.Errorf("解析镜像信息失败: %w", err)
	}

	if len(inspectResults) == 0 {
		return nil, errors.New("镜像信息为空")
	}

	return ParseDockerImageDetail(inspectResults[0])
}
